package com.chindeo.h5.x5.utils;

import android.app.Application;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.util.Log;
import android.widget.Toast;

import com.apkfuns.logutils.LogUtils;
import com.tencent.smtt.sdk.QbSdk;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

public class X5WebUtil {
    //64位
    final private static String PATH = "_64";
    final private static String CORE_VERSION = "45525";
    //32位
//    final private static String PATH = "";
//    final private static String CORE_VERSION = "45416";

    public static void init(Application application) {
        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
            @Override
            public void onViewInitFinished(boolean isX5Core) {
                //x5內核初始化完成的回调，为true表示x5内核加载成功，否则表示x5内核加载失败，会自动切换到系统内核。
                Log.e(X5WebUtil.class.getSimpleName(), " onViewInitFinished isX5Core : " + isX5Core + ", version" + QbSdk.getTbsSdkVersion());
            }

            @Override
            public void onCoreInitFinished() {
                Log.e(X5WebUtil.class.getSimpleName(), " onCoreInitFinished ");

            }
        };
        //x5内核初始化接口
        QbSdk.initX5Environment(application.getApplicationContext(), cb);
    }

    //4.3版本的则没有这个方法
    public static void initStatic(Application application) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                //此方法非常耗时，应当开个线程
                //QbSdk.preinstallStaticTbs(application.getApplicationContext());
            }
        }).start();
    }

    public static void execute(Application application) {
        traverseAssetsCount = 0;
        copyAssetsCount = 0;
        //搜集本地tbs内核信息并上报服务器，服务器返回结果决定使用哪个内核。
        if (!isCreateCoreInfo(application)) {
            Toast.makeText(application, "未发现X5内核，执行安装X5内核..", Toast.LENGTH_SHORT).show();
            if (!isInstallCoreResources(application)) {
                Toast.makeText(application, "未安装X5内核资源包，将使用在线模式..", Toast.LENGTH_SHORT).show();
                init(application);
                return;
            }
            Context context = getCoreResourcesContext(application);
            if (context == null) {
                Toast.makeText(application, "获取X5内核资源包Context==null，将使用在线模式..", Toast.LENGTH_SHORT).show();
                init(application);
                return;
            }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    traverseAssets(context, "core_share");

                    copyAssetsDir2Phone(application, context, "core_share");
                }
            }).start();
            return;
        }
        Toast.makeText(application, "X5内核已安装..", Toast.LENGTH_SHORT).show();
        init(application);
    }

    public static String X5_CORE_RESOURCES_PACKAGE_NAME = "com.chindeo.resources";

    //判断资源apk是否安装
    public static boolean isInstallCoreResources(Context context) {
        try {
            context.getPackageManager().getPackageInfo(X5_CORE_RESOURCES_PACKAGE_NAME, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    public static Context getCoreResourcesContext(Context selfContext) {

        try {
            return selfContext.createPackageContext(X5_CORE_RESOURCES_PACKAGE_NAME, Context.CONTEXT_IGNORE_SECURITY);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            Log.e(X5WebUtil.class.getSimpleName(), "PackageManager.NameNotFoundException:" + e.getMessage());
            return null;
        }
    }

    private static int copyAssetsCount = 0;

    /**
     * 从assets目录中复制整个文件夹内容,考贝到 /data/data/包名/files/目录中
     *
     * @param remoteContext remoteContext 使用CopyFiles类的Activity
     * @param filePath      String  文件路径,如：/assets/aa
     *                      core_path=/应用内部存储路径/app_tbs/core_share
     */
    public static void copyAssetsDir2Phone(Application selfContext, Context remoteContext, String filePath) {
        try {
            String[] fileList = remoteContext.getAssets().list(filePath);
            if (fileList.length > 0) {//如果是目录
                File file = new File((selfContext.getFilesDir().getAbsolutePath() + File.separator + "app_tbs" + PATH + "/" + filePath).replace("/files", ""));
                file.mkdirs();//如果文件夹不存在，则递归
                for (String fileName : fileList) {
                    filePath = filePath + File.separator + fileName;
                    copyAssetsDir2Phone(selfContext, remoteContext, filePath);
                    filePath = filePath.substring(0, filePath.lastIndexOf(File.separator));
                }
            } else {//如果是文件
                InputStream inputStream = remoteContext.getAssets().open(filePath);
                File file = new File((selfContext.getFilesDir().getAbsolutePath() + File.separator + "app_tbs" + PATH + "/" + filePath).replace("/files", ""));
                if (!file.exists() || file.length() == 0) {
                    FileOutputStream fos = new FileOutputStream(file);
                    int len = -1;
                    byte[] buffer = new byte[1024];
                    while ((len = inputStream.read(buffer)) != -1) {
                        fos.write(buffer, 0, len);
                    }
                    fos.flush();
                    inputStream.close();
                    fos.close();
                    Log.e(X5WebUtil.class.getSimpleName(), "复制完成");
                    copyAssetsCount += 1;

                } else {
                    Log.e(X5WebUtil.class.getSimpleName(), "模型文件已存在，无需复制");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(X5WebUtil.class.getSimpleName(), "copyAssetsDir2Phone IOException：" + e.getMessage());

        }
        Log.e(X5WebUtil.class.getSimpleName(), "copyAssetsCount:" + copyAssetsCount);
        int value = Math.abs(traverseAssetsCount - copyAssetsCount);
        if (value <= 2) {
            createCoreInfo(selfContext);
        }
    }

    //是否复制过
    public static boolean isCreateCoreInfo(Context selfContext) {
        File file = new File((selfContext.getFilesDir().getAbsolutePath() + File.separator + "app_tbs" + PATH + "/share/core_info").replace("/files", ""));
        if (!file.exists()) {
            return false;
        }
        return true;
    }


    //应用内部存储路径/app_tbs/share/core_info
    public static void createCoreInfo(Application selfContext) {
//64位
//        #Thu Apr 08 18:55:23 GMT+08:00 2021
//        core_packagename=com.chindeo.webapp
//        app_version=1
//        core_disabled=false
//        core_version=45525
//        core_path=/data/user/0/com.chindeo.webapp/app_tbs_64/core_share
//32位
//        core_packagename=应用包名
//        app_version=1
//        core_version=45416
//        core_disabled=false
//        core_path=/应用内部存储路径/app_tbs/core_share
        StringBuilder coreInfo = new StringBuilder();
        coreInfo.append("core_packagename=" + selfContext.getPackageName()).append("\n")
                .append("app_version=1").append("\n")
                .append("core_version=" + CORE_VERSION).append("\n")
                .append("core_disabled=false").append("\n")
                .append("core_path=" + (selfContext.getFilesDir().getAbsolutePath() + File.separator + "app_tbs" + PATH + "/core_share").replace("/files", ""));
        FileOutputStream out = null;
        try {
            //目标文件
            File file = new File((selfContext.getFilesDir().getAbsolutePath() + File.separator + "app_tbs" + PATH + "/share/core_info").replace("/files", ""));
            //若不存在即创建文件
            if (!file.exists()) {
                if (!file.getParentFile().exists()) {   //如果父文件夹不存在
                    file.getParentFile().mkdirs();      //新建多层文件夹
                }
                try {
                    file.createNewFile();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            //创建文件输入流
            out = new FileOutputStream(file, false);              //如果追加方式用true
            //写入内容
            out.write((coreInfo.toString() + "\n\n").getBytes("utf-8"));      //注意需要转换对应的字符集

        } catch (Exception ex) {
            ex.printStackTrace();
            System.out.println(ex.getMessage());
        } finally {
            try {
                if (out != null) {
                    out.close();   //关闭流
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }

        LogUtils.d("##X5内核安装完成，即将重新启动完成初始化！");
//        selfContext.getMainHandler().post(new Runnable() {
//            @Override
//            public void run() {
//                Toast.makeText(selfContext, "X5内核安装完成，即将重新启动完成初始化！", Toast.LENGTH_LONG).show();
//                X5WebApplication.getMainHandler().postDelayed(new Runnable() {
//                    @Override
//                    public void run() {
//                        try {
//                            ActivityManager manager = (ActivityManager) selfContext.getSystemService(ACTIVITY_SERVICE); //获取应用程序管理器
//                            manager.killBackgroundProcesses(selfContext.getPackageName()); //强制结束当前应用程序
//                            //这种方式退出应用，会结束本应用程序的一切活动,因为本方法会根据应用程序的包名杀死所有进程包括Activity,Service,Notifications等。
                            System.exit(0);
//                        } catch (Exception ignored) {
//                        }
//                    }
//                }, 1500);
//            }
//        });
    }


    private static int traverseAssetsCount = 0;

    /**
     * 遍历assets文件夹
     *
     * @param path 在assets中的路径
     */
    public static void traverseAssets(Context context, String path) {
        AssetManager assetManager = context.getAssets();
        try {
            // 获取path目录下，全部的文件、文件夹
            String[] list = assetManager.list(path);
            if (list == null || list.length <= 0) {
                // 当前为文件时，或者当前目录下为空
                return;
            }
            for (int i = 0; i < list.length; i++) {
                // System.out.println(tab + list[i]);
                Log.e(X5WebUtil.class.getSimpleName(), list[i]);
                String subPath;
                if ("".equals(path)) {
                    // 如果当前是根目录
                    subPath = list[i];
                } else {
                    // 如果当前不是根目录
                    subPath = path + "/" + list[i];
                }
                traverseAssetsCount += 1;
                traverseAssets(context, subPath);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        Log.e(X5WebUtil.class.getSimpleName(), "traverseAssetsCount:" + traverseAssetsCount);

    }
    /**
     * 检测某个应用是否安装
     *
     * @param context
     * @param packageName
     * @return boolean
     */
    public static boolean isAppInstalled(Context context, String packageName) {
        try {
            context.getPackageManager().getPackageInfo(packageName, 0);
            return true;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    /**
     * 启动某App  默认是主页面
     *
     * @param context
     */
    public static void launchApp(Context context, String appPackageName) {
        // 判断是否安装过App，否则去下载
        if (isAppInstalled(context, appPackageName)) {
            context.startActivity(context.getPackageManager().getLaunchIntentForPackage(appPackageName));
        } else {
            //下载
            Toast.makeText(context, appPackageName + "未安装", Toast.LENGTH_SHORT).show();
        }
    }


}
